#ifndef _T_POOL_H_
#define _T_POOL_H_

#include <vector>

/*std::vector vec;
vec.back()
std::vector::const_reverse_iterator*/

//----------------------------------------------
template <typename T, int SIZE>
class TStaticQueue
{
public:
	class const_iterator
	{
	public:
		const_iterator() : m_iIndex(-1), m_pPool(NULL) {}
		const_iterator(int iIndex, const TStaticQueue<T, SIZE>* pPool) : m_iIndex(iIndex), m_pPool(pPool){}

		void		operator=	(const const_iterator& oIt)			{ m_iIndex = oIt.m_iIndex; m_pPool = oIt.m_pPool; }
		bool		operator==	(const const_iterator& oIt) const	{ return m_iIndex == oIt.m_iIndex && m_pPool == oIt.m_pPool; }
		bool		operator!=	(const const_iterator& oIt) const	{ return m_iIndex != oIt.m_iIndex || m_pPool != oIt.m_pPool; }
		const T&	operator*	() const							{ return m_pPool->m_oArray[m_iIndex]; }
		void		operator++	(int);
	private:
		int						m_iIndex;
		const TStaticQueue<T, SIZE>*	m_pPool;
	};

	class const_reverse_iterator
	{
	public:
		const_reverse_iterator() : m_iIndex(-1), m_pPool(NULL) {}
		const_reverse_iterator(int iIndex, const TStaticQueue<T, SIZE>* pPool) : m_iIndex(iIndex), m_pPool(pPool){}

		void		operator=	(const const_reverse_iterator& oIt)			{ m_iIndex = oIt.m_iIndex; m_pPool = oIt.m_pPool; }
		bool		operator==	(const const_reverse_iterator& oIt) const	{ return m_iIndex == oIt.m_iIndex && m_pPool == oIt.m_pPool; }
		bool		operator!=	(const const_reverse_iterator& oIt) const	{ return m_iIndex != oIt.m_iIndex || m_pPool != oIt.m_pPool; }
		const T&	operator*	() const									{ return m_pPool->m_oArray[m_iIndex]; }
		void		operator++	(int);
	private:
		int						m_iIndex;
		const TStaticQueue<T, SIZE>*	m_pPool;
	};

	TStaticQueue() : m_iBegin(0), m_iEnd(0), m_iCount(0) {}

	T*						push		(const T& oVal);
	int						size		() const { return m_iCount; }
	int						capacity	() const { return SIZE; }
	const_iterator			begin		() const { return const_iterator(m_iBegin, this); }
	const_reverse_iterator	rbegin		() const
	{
		int iIndex = m_iEnd - 1;
		if (iIndex < 0)
			iIndex += s_iRealCapacity;
		return const_reverse_iterator(iIndex, this);
	}
	T&						back		();
	const T&				back		() const;
	const_iterator			end			() const { return const_iterator(m_iEnd, this); }
	const_reverse_iterator	rend		() const
	{
		int iIndex = m_iBegin - 1;
		if (iIndex < 0)
			iIndex += s_iRealCapacity;
		return const_reverse_iterator(iIndex, this);
	}
	void					clear		();

private:

	friend class const_iterator;

	static const int s_iRealCapacity = SIZE+1;

	T		m_oArray[s_iRealCapacity];
	int		m_iBegin;
	int		m_iEnd;
	int		m_iCount;
};

//----------------------------------------------
template <typename T, int SIZE>
const T& TStaticQueue<T, SIZE>::back () const
{
	int iIndex = m_iBegin + m_iCount - 1;
	if (iIndex >= s_iRealCapacity)
		iIndex -= s_iRealCapacity;
	return m_oArray[iIndex];
}

//----------------------------------------------
template <typename T, int SIZE>
T& TStaticQueue<T, SIZE>::back ()
{
	int iIndex = m_iBegin + m_iCount - 1;
	if (iIndex >= s_iRealCapacity)
		iIndex -= s_iRealCapacity;
	return m_oArray[iIndex];
}

//----------------------------------------------
template <typename T, int SIZE>
T* TStaticQueue<T, SIZE>::push (const T& oVal)
{
	T* pOld = NULL;
	m_oArray[m_iEnd] = oVal;
	m_iEnd++;
	if (m_iCount == SIZE)
	{
		pOld = &m_oArray[m_iBegin];
		m_iBegin++;
	}
	else
		m_iCount++;
	if (m_iEnd == s_iRealCapacity)
		m_iEnd -= s_iRealCapacity;
	if (m_iBegin == s_iRealCapacity)
		m_iBegin -= s_iRealCapacity;

	return pOld;
}

//----------------------------------------------
template <typename T, int SIZE>
void TStaticQueue<T, SIZE>::clear ()
{
	m_iBegin = 0;
	m_iEnd = 0;
	m_iCount = 0;
}

//----------------------------------------------
template <typename T, int SIZE>
void TStaticQueue<T, SIZE>::const_iterator::operator ++(int)
{
	m_iIndex++;
	if (m_iIndex >= TStaticQueue<T, SIZE>::s_iRealCapacity)
		m_iIndex -= TStaticQueue<T, SIZE>::s_iRealCapacity;
}

//----------------------------------------------
template <typename T, int SIZE>
void TStaticQueue<T, SIZE>::const_reverse_iterator::operator ++(int)
{
	m_iIndex--;
	if (m_iIndex < 0)
		m_iIndex += TStaticQueue<T, SIZE>::s_iRealCapacity;
}


#endif
